#pragma once

#include <stdexcept>
#include <string>
#include <vector>
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#include "thirdparty/cxxopts/cxxopts.hpp"
#include "../corelib/singleton.hpp"
#include "../corelib//logger/appender.hh"
#include "../corelib/util/allocator.hh"

namespace kratos { namespace engine {

// command line options
class CommandOptions {
public:
    using StringVector = std::vector<std::string>;

public:
    // ctor
    CommandOptions();
    // dtor
    ~CommandOptions();
    // load command arguments
    // @param argc pass from main()
    // @param argv pass from main()
    // @retval true 
    // @retval false fail
    bool load(int argc, const char** argv);
    // returns path of configuration file
    const std::string& getConfigFilePath() const;
    // returns daemonizing flag
    bool isStartAsService() const;
    // returns service name
    const std::string& getServiceName() const;
    // returns plugin path
    const std::string& getPluginPath() const;
    // returns pid file path
    const std::string& getPIDFilePath() const;
    // Is debug mode?
    bool isDebug() const;
    // returns all .cfg file name
    const StringVector& getConfigFileNames() const;
    // returns log appender type of debug mode
    kratos::corelib::AppenderType getAppenderType();
    // returns the maximum frequency of main cycle, frame/second
    int getFrame();

private:
    std::string configFilePath_; // path of configuration file
    bool startAsService_; // daemonizing flag
    std::string serviceName_; // service name
    std::string pluginPath_; // plugin path
    std::string pidFilePath_; // pid file path
    bool debug_; // Is debug mode?
    StringVector configFileNames_;
    kratos::corelib::AppenderType debugLogType_; // The log appender type of debug mode
    int frame_; // The maximum frequency of main cycle, frame/second
};

}}

#define CommandOptionsRef (*kratos::corelib::Singleton<kratos::engine::CommandOptions>::instance())
